﻿using SimpleBoard.Project.Data;
using SimpleBoard.ControllerMeta;
using SimpleBoard.Designer.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SimpleBoard.Project.Binding;
using SimpleBoard.DependencyInjection;
using SimpleBoard.Designer.Services;
using SimpleBoard.Designer.ViewModels;

namespace SimpleBoard.Designer.Controls
{
    /// <summary>
    /// StringSetter.xaml 的交互逻辑
    /// </summary>
    [InjectAs(InjectionType.Transient)]
    public partial class StringSetter : UserControl
    {
        public StringSetter(DataProtocolDesignerPageViewModel controllerService)
        {
            InitializeComponent();
            DataContext = this;
            this.viewModel = controllerService;
        }

        public string Value
        {
            get { return (string)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(string), typeof(StringSetter), new PropertyMetadata(""));

        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }


        // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title", typeof(string), typeof(StringSetter), new PropertyMetadata("属性值"));

        private FrameworkElement targetElement = null!;
        private PropertyInfo targetProperty = null!;

        private readonly DataProtocolDesignerPageViewModel viewModel;

        public FrameworkElement TargetElement
        {
            get => targetElement;
            set
            {
                targetElement = value;
                if (TargetProperty == null) return;
                Value = targetElement.GetPropertyValue(TargetProperty.Name)!.ToString()!;
            }
        }

        public PropertyInfo TargetProperty
        {
            get => targetProperty;
            set
            {
                targetProperty = value;
                if (TargetElement == null) return;
                Value = targetElement.GetPropertyValue(TargetProperty.Name)!.ToString()!;
            }
        }

        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            object value = TargetProperty.Type switch
            {
                PropertyType.String => this.Value,
                PropertyType.Int32 => int.Parse(this.Value),
                PropertyType.Bool => bool.Parse(this.Value),
                PropertyType.Double => double.Parse(this.Value),

                _ => throw new NotImplementedException()
            };

            TargetElement.SetPropertyValue(TargetProperty.Name, value);
        }

        private void Label_Drop(object sender, DragEventArgs e)
        {
            if (!e.Data.GetDataPresent(typeof(DataUnit))) return;
            var dataUnit = (DataUnit)e.Data.GetData(typeof(DataUnit));
            if (dataUnit is null) return;

            // 类型匹配检查
            switch (dataUnit.Type)
            {
                case DataUnitType.String:
                    if (this.targetProperty.Type != PropertyType.String) return;
                    break;
                case DataUnitType.Int32:
                    if (this.targetProperty.Type != PropertyType.Int32) return;
                    break;
                case DataUnitType.Float32:
                    if (this.targetProperty.Type != PropertyType.Double) return;
                    break;
                case DataUnitType.Bool:
                    if (this.targetProperty.Type != PropertyType.Bool) return;
                    break;
            }
            var binding = new DataBinding
            {
                ControlName =  this.targetElement.Name,
                DataUnitName = dataUnit.Name,
                PropertyName = this.targetProperty.Name,
            };

            // 移除已存在的绑定
            var exsistsQuery = from bind in viewModel.DataBindings
                               where bind.ControlName == this.targetElement.Name
                               where bind.PropertyName == this.targetProperty.Name
                               select bind;
            if (exsistsQuery.Any())
            {
                viewModel.DataBindings.Remove(exsistsQuery.Single());
            }

            viewModel.DataBindings.Add(binding);
        }
    }
}
